﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using Microsoft.Xna.Framework.Content.Pipeline;
using System;

namespace FxArchitect.ContentPipeline
{
    public class ContentProcessorInfo
    {
        Type m_processorType;
        object m_instance;

        [Browsable(false)]
        public string TypeName { get { return m_processorType.Name; } }
        public string DisplayName;

        [Browsable(true)]
        public object Instance { get { return m_instance; } set { m_instance = value; } }

        ContentProcessorInfo() { }
        public ContentProcessorInfo(ContentProcessorAttribute attr, Type type)
        {
            DisplayName = attr.DisplayName;
            m_processorType = type;
        }

        public object CreateInstance()
        {
            return m_processorType.GetConstructor(Type.EmptyTypes).Invoke(null);
        }

        public override string ToString()
        {
            return DisplayName;
        }

        public ContentProcessorInfo Clone()
        {
            return new ContentProcessorInfo()
            {
                m_processorType = this.m_processorType,
                DisplayName = this.DisplayName,
                m_instance = CreateInstance()
            };
        }
    }

    public class ContentProcessorInfoCollection : KeyedCollection<string, ContentProcessorInfo>
    {
        protected override string GetKeyForItem(ContentProcessorInfo item)
        {
            return item.TypeName;
        }
    }

    class ContentProcessorConverter : ExpandableObjectConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {   // show a combobox for this element
            return true;
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {   // don't allow typing the processor name
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            List<ContentProcessorInfo> processorNames = new List<ContentProcessorInfo>();
            foreach (ContentExtensionProject item in ContentProject.ContentExtensions)
            {
                foreach (ContentProcessorInfo info in item.Processors)
                {
                    processorNames.Add(info);
                }
            }
            return new StandardValuesCollection(processorNames);
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string strValue = value as string;
            if (strValue != null)
                return ContentProject.ContentExtensions.FindProcessorByDisplayName(strValue);
            return base.ConvertFrom(context, culture, value);
        }
    }
}
